
#include "string.h"
#include "../lib/data_pool_named.h"
#include "jxos_config.h"
#include "jxos_mail_box.h"
#include "jxos_malloc.h"
#include "jxos_registry.h"

#if (JXOS_MAIL_BOX_ENABLE == 1)

static DATA_POOL_NAMED_STRUCT mail_box_handle_list[MAIL_BOX_MAX];
static uint8_t mail_box_handle_list_count = 0;
JXOS_MALLOC_MEM_POOL_STRUCT mail_box_handle_list_mem_pool;

void jxos_mail_box_init(void)
{
    memset(mail_box_handle_list, 0, sizeof(DATA_POOL_NAMED_STRUCT)*MAIL_BOX_MAX);
    mail_box_handle_list_mem_pool.mem_pool = (void*)mail_box_handle_list;
    mail_box_handle_list_mem_pool.len = sizeof(DATA_POOL_NAMED_STRUCT)*MAIL_BOX_MAX;
    mail_box_handle_list_mem_pool.offset = 0;
    mail_box_handle_list_count = 0;
}

JXOS_MAIL_BOX_HANDLE jxos_mail_box_create(uint8_t* space,
						uint16_t space_len,
						uint8_t data_size,
						char* mail_box_name)
{
    DATA_POOL_NAMED_STRUCT* h = 0;
    if(jxos_malloc_set_mem_pool(&mail_box_handle_list_mem_pool) == 0){
        while(1);
    }
    if((space == 0)
        ||(space_len == 0)
        ||(data_size == 0)
        ||(mail_box_name == 0)
    ||(space_len < data_size)
	||(data_size < 3)){
        return 0;
    }

	if(space_len/data_size > 255){
		space_len = data_size*255;	//make sure the number of mails is less the 255
	}

    h = jxos_malloc(sizeof(DATA_POOL_NAMED_STRUCT));
    if(h != 0){
		if(data_pool_named_init(h, space, space_len, data_size) == 1){
#if (JXOS_REGISTRY_ENABLE == 1)
            if(jxos_registry_register(mail_box_name, h) == 1){
#endif
                mail_box_handle_list_count++;
#if (JXOS_REGISTRY_ENABLE == 1)
            }
            else{
                h = 0;
            }
#endif
		}
		else{
			h = 0;
		}
    }

    return (JXOS_MAIL_BOX_HANDLE)h;
}

uint8_t jxos_mail_box_send(JXOS_MAIL_BOX_HANDLE mail_box,
							uint8_t* data_to_send, uint8_t data_to_send_len)
{
    if((mail_box == 0)
       ||(mail_box < (void*)(mail_box_handle_list_mem_pool.mem_pool))
       ||(mail_box > (void*)(mail_box_handle_list_mem_pool.mem_pool+mail_box_handle_list_mem_pool.offset))){
        return 0;
    }

	return data_pool_named_write_data((DATA_POOL_NAMED_STRUCT*)mail_box, 0, data_to_send, data_to_send_len);
}

uint8_t jxos_mail_box_receive(JXOS_MAIL_BOX_HANDLE mail_box, char* receiver_name,
							uint8_t* receive_buffer, uint8_t* receive_data_len)
{
	uint8_t ret;
    if((mail_box == 0)
       ||(mail_box < (void*)(mail_box_handle_list_mem_pool.mem_pool))
       ||(mail_box > (void*)(mail_box_handle_list_mem_pool.mem_pool+mail_box_handle_list_mem_pool.offset))
	   ||(receiver_name == 0)){
        return 0;
    }

    ret = data_pool_named_read_data((DATA_POOL_NAMED_STRUCT*)mail_box, receiver_name, 0, receive_buffer, receive_data_len);
	if(ret != 0){
		return data_pool_named_del_data((DATA_POOL_NAMED_STRUCT*)mail_box, 0, receiver_name);
	}
	else{
        return 0;
	}
}

uint8_t jxos_mail_box_check_empty(JXOS_MAIL_BOX_HANDLE mail_box)
{
    if((mail_box == 0)
       ||(mail_box < (void*)(mail_box_handle_list_mem_pool.mem_pool))
       ||(mail_box > (void*)(mail_box_handle_list_mem_pool.mem_pool+mail_box_handle_list_mem_pool.offset))){
        return 0xff;
    }

    return data_pool_named_check_empty((DATA_POOL_NAMED_STRUCT*)mail_box, 0, 0);
}

uint8_t jxos_mail_box_check_full(JXOS_MAIL_BOX_HANDLE mail_box)
{
    if((mail_box == 0)
       ||(mail_box < (void*)(mail_box_handle_list_mem_pool.mem_pool))
       ||(mail_box > (void*)(mail_box_handle_list_mem_pool.mem_pool+mail_box_handle_list_mem_pool.offset))){
        return 0xff;
    }

    return data_pool_named_check_full((DATA_POOL_NAMED_STRUCT*)mail_box, 0, 0);
}

uint8_t jxos_mail_box_clean_up(JXOS_MAIL_BOX_HANDLE mail_box, char*receiver_name)
{
    if((mail_box == 0)
       ||(mail_box < (void*)(mail_box_handle_list_mem_pool.mem_pool))
       ||(mail_box > (void*)(mail_box_handle_list_mem_pool.mem_pool+mail_box_handle_list_mem_pool.offset))
	   ||(receiver_name == 0)){
        return 0;
    }

    return data_pool_named_clr_all((DATA_POOL_NAMED_STRUCT*)mail_box, receiver_name, receiver_name);
}

uint8_t jxos_mail_box_receiver_name_register(JXOS_MAIL_BOX_HANDLE mail_box, char* receiver_name)
{
    if((mail_box == 0)
       ||(mail_box < (void*)(mail_box_handle_list_mem_pool.mem_pool))
       ||(mail_box > (void*)(mail_box_handle_list_mem_pool.mem_pool+mail_box_handle_list_mem_pool.offset))
	   ||(receiver_name == 0)){
        return 0;
    }

	return data_pool_named_reader_name_register((DATA_POOL_NAMED_STRUCT*)mail_box, receiver_name);
}

uint8_t jxos_mail_box_receiver_name_cancel(JXOS_MAIL_BOX_HANDLE mail_box, char* receiver_name)
{
    if((mail_box == 0)
       ||(mail_box < (void*)(mail_box_handle_list_mem_pool.mem_pool))
       ||(mail_box > (void*)(mail_box_handle_list_mem_pool.mem_pool+mail_box_handle_list_mem_pool.offset))
	   ||(receiver_name == 0)){
        return 0;
    }

	return data_pool_named_reader_name_cancel((DATA_POOL_NAMED_STRUCT*)mail_box, receiver_name);
}

#if (JXOS_REGISTRY_ENABLE == 1)
JXOS_MAIL_BOX_HANDLE jxos_mail_box_get_handle(char* mail_box_name)
{
    if(mail_box_name == 0){
        return 0;
    }
    return (JXOS_MAIL_BOX_HANDLE)jxos_registry_find(mail_box_name);
}
#endif

uint8_t jxos_mail_box_check_empty_all(void)
{
	uint8_t i;
	uint16_t num;
	for(i = 0; i < mail_box_handle_list_count; i++){
		num = data_pool_named_check_data_num(&(mail_box_handle_list[i]), 0, 0);
		if((num != 0xffff)&&(num != 0)){
			return 0;
		}
	}
	return 1;
}
#endif
